package ca.cbc.msb.daemon;

import ca.cbc.medialib.util.ApplicationContextUtil;
import ca.cbc.msb.guice.MSBModule;
import ca.cbc.msb.mediacms.NotificationListener;
import ca.cbc.msb.mq.MSBMessageConsumer;
import ca.cbc.msb.util.ExceptionHandler;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @author Arash Bizhanzadeh <arash.bizhan-zadeh@cbc.ca>
 *         Date: 28/01/11
 *         Time: 3:28 PM
 *         Copyrighted to CBC. All rights reserved.
 */
public class Main {
    private static Logger logger= LoggerFactory.getLogger(Main.class);
    @Inject
    @Named("NewReleaseNotificationListener")
    private NotificationListener newReleaseListener;

    @Inject
    @Named("DeleteReleaseNotificationListener")
    private NotificationListener deleteReleaseListener;

    @Inject
    @Named("ChangeMediaNotificationListener")
    private NotificationListener changeMediaListener;

    @Inject
    @Named("ReleaseNotificationQueueConsumer")
    private List<MSBMessageConsumer> releaseNotificationQueueConsumer;

    @Inject
    @Named("ChangeNotificationQueueConsumer")
    private List<MSBMessageConsumer> changeNotificationQueueConsumer;

    @Inject @Named("DeleteNotificationQueueConsumer")
    private List<MSBMessageConsumer> deleteNotificationQueueConsumer;

    @Inject @Named("NewReleaseQueueConsumer")
    private List<MSBMessageConsumer> newReleaseQueueConsumers;

    @Inject @Named("ChangeMediaQueueConsumer")
    private List<MSBMessageConsumer> changeMediaQueueConsumers;

    @Inject @Named("DeleteReleaseQueueConsumer")
    private List<MSBMessageConsumer> deleteReleaseQueueConsumers;

    @Inject @Named("VerificationQueueConsumer")
    private List<MSBMessageConsumer> yospaceVerificationQueueConsumers;

    @Inject @Named("FailedVerificationQueueConsumer")
    private List<MSBMessageConsumer>  failedVerificationQueueConsumers;

    @Inject @Named("GeneralFailedConsumer")
    private List<MSBMessageConsumer> generalFailedConsumers;

    public static void main(String[] strs){
        logger.debug("Creating injectors");
        Injector injector = Guice.createInjector(new MSBModule());
        Main main = injector.getInstance(Main.class);
        logger.info("Starting");
        main.start();
    }

    public void start(){

        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
    	// add a shutdown hook for the above context... 
    	ApplicationContextUtil.instance.getApplicationContext().registerShutdownHook();
//        logger.debug("creating hibernat session factory");
//        HibernateUtil.createSessionFactory();  
        logger.debug("new release listener starting");
        this.newReleaseListener.start();
        logger.debug("delete release listener starting");
        this.deleteReleaseListener.start();
        logger.debug("change meda listener starting");
        this.changeMediaListener.start();
        logger.debug("new release consumer starting");
        startConsumers(newReleaseQueueConsumers);
        logger.debug("change media consumer starting");
        startConsumers(changeMediaQueueConsumers);
        logger.debug("delete release consumer starting");
        startConsumers(deleteReleaseQueueConsumers);
        startConsumers(yospaceVerificationQueueConsumers);
        startConsumers(releaseNotificationQueueConsumer);
        startConsumers(changeNotificationQueueConsumer);
        startConsumers(deleteNotificationQueueConsumer);
        startConsumers(failedVerificationQueueConsumers);
        startConsumers(generalFailedConsumers);
    }

    public void stop(){
        logger.info("Stopping the main");
        this.newReleaseListener.stop();
        logger.debug("newReleaseListener stopped");
        this.deleteReleaseListener.stop();
        logger.debug("deleteReleaseListener Stopped");
        this.changeMediaListener.stop();
        stopConsumers(newReleaseQueueConsumers);
        stopConsumers(changeMediaQueueConsumers);
        stopConsumers(deleteReleaseQueueConsumers);
        stopConsumers(yospaceVerificationQueueConsumers);
        stopConsumers(changeNotificationQueueConsumer);
        stopConsumers(releaseNotificationQueueConsumer);
        stopConsumers(deleteNotificationQueueConsumer);
        stopConsumers(failedVerificationQueueConsumers);
        stopConsumers(generalFailedConsumers);
        //disconnect DB
//        HibernateUtil.shutdown();
        System.exit(1);
    }

    private void startConsumers(List<MSBMessageConsumer> list){
        for (MSBMessageConsumer consumer : list ){
            consumer.start();
        }
    }

    private void stopConsumers(List<MSBMessageConsumer> list){
        for(MSBMessageConsumer consumer : list){
            consumer.stop();
        }
    }

}
